home *** CD-ROM | disk | FTP | other *** search
/ SPACE 1 / SPACE - Library 1 - Volume 1.iso / utilitys / 47 / viscalc / interp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-03-30  |  14.6 KB  |  616 lines

  1. /*    SC    A Spreadsheet Calculator
  2.  
  3.  *        Expression interpreter and assorted support routines.
  4.  
  5.  *
  6.  
  7.  *        original by James Gosling, September 1982
  8.  
  9.  *        modified by Mark Weiser and Bruce Israel, 
  10.  
  11.  *            University of Maryland
  12.  
  13.  *
  14.  
  15.  *              More mods Robert Bond, 12/86
  16.  
  17.  *        Major mods to run on VMS and AMIGA, 1/17/87
  18.  
  19.  */
  20.  
  21.  
  22.  
  23. #include "sc.h"
  24.  
  25. #define DEFCOLDELIM ':'
  26.  
  27.  
  28.  
  29. char *malloc();
  30.  
  31.  
  32.  
  33. double dosum(minr, minc, maxr, maxc)
  34.  
  35. int minr, minc, maxr, maxc;
  36.  
  37. {
  38.  
  39.     double v;
  40.  
  41.     register r,c;
  42.  
  43.     register struct ent *p;
  44.  
  45.  
  46.  
  47.     v = 0;
  48.  
  49.     for (r = minr; r<=maxr; r++)
  50.  
  51.     for (c = minc; c<=maxc; c++)
  52.  
  53.         if ((p = tbl[r][c]) && p->flags&is_valid)
  54.  
  55.         v += p->v;
  56.  
  57.     return v;
  58.  
  59. }
  60.  
  61.  
  62.  
  63. double doprod(minr, minc, maxr, maxc)
  64.  
  65. int minr, minc, maxr, maxc;
  66.  
  67. {
  68.  
  69.     double v;
  70.  
  71.     register r,c;
  72.  
  73.     register struct ent *p;
  74.  
  75.  
  76.  
  77.     v = 1;
  78.  
  79.     for (r = minr; r<=maxr; r++)
  80.  
  81.     for (c = minc; c<=maxc; c++)
  82.  
  83.         if ((p = tbl[r][c]) && p->flags&is_valid)
  84.  
  85.         v *= p->v;
  86.  
  87.     return v;
  88.  
  89. }
  90.  
  91.  
  92.  
  93. double doavg(minr, minc, maxr, maxc)
  94.  
  95. int minr, minc, maxr, maxc;
  96.  
  97. {
  98.  
  99.     double v;
  100.  
  101.     register r,c,count;
  102.  
  103.     register struct ent *p;
  104.  
  105.  
  106.  
  107.     v = 0;
  108.  
  109.     count = 0;
  110.  
  111.     for (r = minr; r<=maxr; r++)
  112.  
  113.     for (c = minc; c<=maxc; c++)
  114.  
  115.         if ((p = tbl[r][c]) && p->flags&is_valid) {
  116.  
  117.         v += p->v;
  118.  
  119.         count++;
  120.  
  121.         }
  122.  
  123.  
  124.  
  125.     return (v / (double)count);
  126.  
  127. }
  128.  
  129.  
  130.  
  131. double eval(e)
  132.  
  133. register struct enode *e; {
  134.  
  135.     if (e==0) return 0;
  136.  
  137.     switch (e->op) {
  138.  
  139.     case '+':    return (eval(e->e.o.left) + eval(e->e.o.right));
  140.  
  141.     case '-':    return (eval(e->e.o.left) - eval(e->e.o.right));
  142.  
  143.     case '*':    return (eval(e->e.o.left) * eval(e->e.o.right));
  144.  
  145.     case '/':     {    double denom = eval (e->e.o.right);
  146.  
  147.             return denom ? eval(e->e.o.left) / denom : 0; }
  148.  
  149.     case '<':    return (eval(e->e.o.left) < eval(e->e.o.right));
  150.  
  151.     case '=':    return (eval(e->e.o.left) == eval(e->e.o.right));
  152.  
  153.     case '>':    return (eval(e->e.o.left) > eval(e->e.o.right));
  154.  
  155.     case '&':    return (eval(e->e.o.left) != 0.0 &&
  156.  
  157.                    eval(e->e.o.right) != 0.0) ? 1.0 : 0.0;
  158.  
  159.     case '|':    return (eval(e->e.o.left) != 0.0 ||
  160.  
  161.                    eval(e->e.o.right) != 0.0) ? 1.0 : 0.0;
  162.  
  163.     case '?':    return eval(e->e.o.left) ? eval(e->e.o.right->e.o.left)
  164.  
  165.                          : eval(e->e.o.right->e.o.right);
  166.  
  167.     case 'm':    return (-eval(e->e.o.right));
  168.  
  169.     case 'f':    return (eval(e->e.o.right));
  170.  
  171.     case '~':    return (!eval(e->e.o.right));
  172.  
  173.     case 'k':    return (e->e.k);
  174.  
  175.     case 'v':    return (e->e.v->v);
  176.  
  177.     case O_REDUCE('+'):
  178.  
  179.      case O_REDUCE('*'):
  180.  
  181.      case O_REDUCE('a'):
  182.  
  183.         {
  184.  
  185. #ifdef TOS
  186.  
  187.             register r,c;
  188.  
  189.         int maxr, maxc;
  190.  
  191.         int minr, minc;
  192.  
  193. #else
  194.  
  195.             register r,c;
  196.  
  197.         register maxr, maxc;
  198.  
  199.         register minr, minc;
  200.  
  201. #endif
  202.  
  203.         maxr = ((struct ent *) e->e.o.right) -> row;
  204.  
  205.         maxc = ((struct ent *) e->e.o.right) -> col;
  206.  
  207.         minr = ((struct ent *) e->e.o.left) -> row;
  208.  
  209.         minc = ((struct ent *) e->e.o.left) -> col;
  210.  
  211.         if (minr>maxr) r = maxr, maxr = minr, minr = r;
  212.  
  213.         if (minc>maxc) c = maxc, maxc = minc, minc = c;
  214.  
  215.             switch (e->op) {
  216.  
  217.                 case O_REDUCE('+'): return dosum(minr, minc, maxr, maxc);
  218.  
  219.                  case O_REDUCE('*'): return doprod(minr, minc, maxr, maxc);
  220.  
  221.                  case O_REDUCE('a'): return doavg(minr, minc, maxr, maxc);
  222.  
  223.         }
  224.  
  225.         }
  226.  
  227.     }
  228.  
  229. }
  230.  
  231.  
  232.  
  233. #define MAXPROP 7
  234.  
  235.  
  236.  
  237. EvalAll () {
  238.  
  239.     int lastct,repct = 0;
  240.  
  241.  
  242.  
  243.     while ((lastct = RealEvalAll()) && (repct++ <= MAXPROP));
  244.  
  245.  
  246.  
  247.     repct--;
  248.  
  249. }
  250.  
  251.  
  252.  
  253. int RealEvalAll () {
  254.  
  255.     register i,j;
  256.  
  257.     int chgct = 0;
  258.  
  259.     register struct ent *p;
  260.  
  261.     for (i=0; i<=maxrow; i++)
  262.  
  263.     for (j=0; j<=maxcol; j++)
  264.  
  265.         if ((p=tbl[i][j]) && p->expr) {
  266.  
  267.         double v = eval (p->expr);
  268.  
  269.         if (v != p->v) {
  270.  
  271.             p->v = v; chgct++;
  272.  
  273.             p->flags |= (is_changed|is_valid);
  274.  
  275.         }
  276.  
  277.         }
  278.  
  279.     return(chgct);
  280.  
  281. }
  282.  
  283.  
  284.  
  285. struct enode *new(op,a1,a2)
  286.  
  287. struct enode *a1, *a2; {
  288.  
  289.     register struct enode *p = (struct enode *) malloc (sizeof (struct enode));
  290.  
  291.     p->op = op;
  292.  
  293.     switch (op) {
  294.  
  295.     case O_VAR: p->e.v = (struct ent *) a1; break;
  296.  
  297.     case O_CONST: p->e.k = *(double *)&a1; break;
  298.  
  299.     default: p->e.o.left = a1; p->e.o.right = a2;
  300.  
  301.     }
  302.  
  303.     return p;
  304.  
  305. }
  306.  
  307.  
  308.  
  309. copy (dv, v1, v2)
  310.  
  311. struct ent *dv, *v1, *v2;
  312.  
  313. {
  314.  
  315.     register r,c;
  316.  
  317.     register struct ent *p;
  318.  
  319.     register struct ent *n;
  320.  
  321.     register deltar, deltac;
  322.  
  323.     int maxr, maxc;
  324.  
  325.     int minr, minc;
  326.  
  327.     int dr, dc;
  328.  
  329.  
  330.  
  331.     dr = dv->row;
  332.  
  333.     dc = dv->col;
  334.  
  335.     maxr = v2->row;
  336.  
  337.     maxc = v2->col;
  338.  
  339.     minr = v1->row;
  340.  
  341.     minc = v1->col;
  342.  
  343.     if (minr>maxr) r = maxr, maxr = minr, minr = r;
  344.  
  345.     if (minc>maxc) c = maxc, maxc = minc, minc = c;
  346.  
  347.     if (dr+maxr-minr >= MAXROWS  || 
  348.  
  349.            dc+maxc-minc >= MAXCOLS) {
  350.  
  351.     error ("The table can't be any bigger");
  352.  
  353.     return;
  354.  
  355.     }
  356.  
  357.     deltar = dr-minr;
  358.  
  359.     deltac = dc-minc;
  360.  
  361.     FullUpdate++;
  362.  
  363.     for (r = minr; r<=maxr; r++)
  364.  
  365.     for (c = minc; c<=maxc; c++) {
  366.  
  367.         n = lookat (r+deltar, c+deltac);
  368.  
  369.         clearent(n);
  370.  
  371.         if (p = tbl[r][c]) {
  372.  
  373.         n -> v = p -> v;
  374.  
  375.         n -> flags = p -> flags;
  376.  
  377.         n -> expr = copye(p->expr, deltar, deltac);
  378.  
  379.         n -> label = 0;
  380.  
  381.         if (p -> label) {
  382.  
  383.             n -> label = (char *)
  384.  
  385.                  malloc (strlen (p -> label) + 1);
  386.  
  387.             strcpy (n -> label, p -> label);
  388.  
  389.         }
  390.  
  391.         }
  392.  
  393.     }
  394.  
  395. }
  396.  
  397.  
  398.  
  399. let (v, e)
  400.  
  401. struct ent *v;
  402.  
  403. struct enode *e; {
  404.  
  405.     efree (v->expr);
  406.  
  407.     if (constant(e)) {
  408.  
  409.     v->v = eval(e);
  410.  
  411.     v->expr = 0;
  412.  
  413.     efree(e);
  414.  
  415.     } else
  416.  
  417.     v->expr = e;
  418.  
  419.     v->flags |= (is_changed|is_valid);
  420.  
  421.     changed++;
  422.  
  423.     modflg++;
  424.  
  425. }
  426.  
  427.  
  428.  
  429. clearent (v)
  430.  
  431. struct ent *v; {
  432.  
  433.     if (!v)
  434.  
  435.     return;
  436.  
  437.     label(v,"",-1);
  438.  
  439.     v->v = 0;
  440.  
  441.     if (v->expr)
  442.  
  443.     efree(v->expr);
  444.  
  445.     v->expr = 0;
  446.  
  447.     v->flags |= (is_changed);
  448.  
  449.     v->flags &= ~(is_valid);
  450.  
  451.     changed++;
  452.  
  453.     modflg++;
  454.  
  455. }
  456.  
  457.  
  458.  
  459. constant(e)
  460.  
  461. register struct enode *e; {
  462.  
  463.     return e==0 || e->op == O_CONST 
  464.  
  465.     || (e->op != O_VAR
  466.  
  467.      && (e->op&~0177) != O_REDUCE(0)
  468.  
  469.      && constant (e->e.o.left)
  470.  
  471.      && constant(e->e.o.right));
  472.  
  473. }
  474.  
  475.  
  476.  
  477. efree (e)
  478.  
  479. register struct enode *e; {
  480.  
  481.     if (e) {
  482.  
  483.     if (e->op != O_VAR && e->op !=O_CONST && (e->op&~0177) != O_REDUCE(0)) {
  484.  
  485.         efree (e->e.o.left);
  486.  
  487.         efree (e->e.o.right);
  488.  
  489.     }
  490.  
  491.     free (e);
  492.  
  493.     }
  494.  
  495. }
  496.  
  497.  
  498.  
  499. label (v, s, flushdir)
  500.  
  501. register struct ent *v;
  502.  
  503. register char *s; {
  504.  
  505.     if (v) {
  506.  
  507.     if (flushdir==0 && v->flags&is_valid) {
  508.  
  509.         register struct ent *tv;
  510.  
  511.         if (v->col>0 && ((tv=lookat(v->row,v->col-1))->flags&is_valid)==0)
  512.  
  513.         v = tv, flushdir = 1;
  514.  
  515.         else if (((tv=lookat (v->row,v->col+1))->flags&is_valid)==0)
  516.  
  517.         v = tv, flushdir = -1;
  518.  
  519.         else flushdir = -1;
  520.  
  521.     }
  522.  
  523.     if (v->label) free(v->label);
  524.  
  525.     if (s && s[0]) {
  526.  
  527.         v->label = (char *) malloc (strlen(s)+1);
  528.  
  529.         strcpy (v->label, s);
  530.  
  531.     } else v->label = 0;
  532.  
  533.     v->flags |= is_lchanged;
  534.  
  535.     if (flushdir<0) v->flags |= is_leftflush;
  536.  
  537.     else v->flags &= ~is_leftflush;
  538.  
  539.     FullUpdate++;
  540.  
  541.     modflg++;
  542.  
  543.     }
  544.  
  545. }
  546.  
  547.  
  548.  
  549. decodev (v)
  550.  
  551. register struct ent *v; {
  552.  
  553.     if (v) sprintf (line+linelim, "%s%d", coltoa(v->col), v->row);
  554.  
  555.     else sprintf (line+linelim,"VAR?");
  556.  
  557.     linelim += strlen (line+linelim);
  558.  
  559. }
  560.  
  561.  
  562.  
  563. char *
  564.  
  565. coltoa(col)
  566.  
  567. int col;
  568.  
  569. {
  570.  
  571.     static char rname[3];
  572.  
  573.     register char *p = rname;
  574.  
  575.  
  576.  
  577.     if (col < 0 || col > 25*26) 
  578.  
  579.     debug("coltoa: invalid col: %d", col);
  580.  
  581.  
  582.  
  583.     if (col > 25) {
  584.  
  585.     *p++ = col/26 + 'A' - 1;
  586.  
  587.     col %= 26;
  588.  
  589.     }
  590.  
  591.     *p++ = col+'A';
  592.  
  593.     *p = 0;
  594.  
  595.     return(rname);
  596.  
  597. }
  598.  
  599.  
  600.  
  601. decompile(e, priority)
  602.  
  603. register struct enode *e; {
  604.  
  605.     register char *s;
  606.  
  607.     if (e) {
  608.  
  609.     int mypriority;
  610.  
  611.     switch (e->op) {
  612.  
  613.     default: mypriority = 99; break;
  614.  
  615.     case '?': mypriority = 1; break;
  616.  
  617.     case ':': mypriority = 2; break;
  618.  
  619.     case '|': mypriority = 3; break;
  620.  
  621.     case '&': mypriority = 4; break;
  622.  
  623.     case '<': case '=': case '>': mypriority = 6; break;
  624.  
  625.     case '+': case '-': mypriority = 8; break;
  626.  
  627.     case '*': case '/': mypriority = 10; break;
  628.  
  629.     }
  630.  
  631.     if (mypriority<priority) line[linelim++] = '(';
  632.  
  633.     switch (e->op) {
  634.  
  635.     case 'f':    { 
  636.  
  637.                 for (s="fixed "; line[linelim++] = *s++;);
  638.  
  639.                 linelim--;
  640.  
  641.                 decompile (e->e.o.right, 30);
  642.  
  643.                 break;
  644.  
  645.             }
  646.  
  647.     case 'm':    line[linelim++] = '-';
  648.  
  649.             decompile (e->e.o.right, 30);
  650.  
  651.             break;
  652.  
  653.     case '~':    line[linelim++] = '~';
  654.  
  655.             decompile (e->e.o.right, 30);
  656.  
  657.             break;
  658.  
  659.     case 'v':    decodev (e->e.v);
  660.  
  661.             break;
  662.  
  663.     case 'k':    sprintf (line+linelim,"%.8g",e->e.k);
  664.  
  665.             linelim += strlen (line+linelim);
  666.  
  667.             break;
  668.  
  669.     case O_REDUCE('+'):
  670.  
  671.             for (s="@sum("; line[linelim++] = *s++;);
  672.  
  673.             goto more;
  674.  
  675.     case O_REDUCE('*'):
  676.  
  677.             for (s="@prod("; line[linelim++] = *s++;);
  678.  
  679.             goto more;
  680.  
  681.     case O_REDUCE('a'):
  682.  
  683.             for (s="@avg("; line[linelim++] = *s++;);
  684.  
  685.     more:        linelim--;
  686.  
  687.             decodev (e->e.o.left);
  688.  
  689.             line[linelim++] = ':';
  690.  
  691.             decodev (e->e.o.right);
  692.  
  693.             line[linelim++] = ')';
  694.  
  695.             break;
  696.  
  697.  
  698.  
  699.     default:    decompile (e->e.o.left, mypriority);
  700.  
  701.             line[linelim++] = e->op;
  702.  
  703.             decompile (e->e.o.right, mypriority+1);
  704.  
  705.             break;
  706.  
  707.     }
  708.  
  709.     if (mypriority<priority) line[linelim++] = ')';
  710.  
  711.     } else line[linelim++] = '?';
  712.  
  713. }
  714.  
  715.  
  716.  
  717. editv (row, col) {
  718.  
  719.     sprintf (line, "let %s%d = ", coltoa(col), row);
  720.  
  721.     linelim = strlen(line);
  722.  
  723.     editexp(row,col);
  724.  
  725. }
  726.  
  727.  
  728.  
  729. editexp(row,col) {
  730.  
  731.     register struct ent *p;
  732.  
  733.     p = lookat (row, col);
  734.  
  735.     if (p->flags&is_valid)
  736.  
  737.     if (p->expr) {
  738.  
  739.         decompile (p->expr);
  740.  
  741.         line[linelim] = 0;
  742.  
  743.     } else {
  744.  
  745.         sprintf (line+linelim, "%.8g", p->v);
  746.  
  747.         linelim += strlen (line+linelim);
  748.  
  749.     }
  750.  
  751. }
  752.  
  753.  
  754.  
  755. edits (row, col) {
  756.  
  757.     register struct ent *p = lookat (row, col);
  758.  
  759.     sprintf (line, "%sstring %s%d = \"",
  760.  
  761.             ((p->flags&is_leftflush) ? "left" : "right"),
  762.  
  763.             coltoa(col), row);
  764.  
  765.     linelim = strlen(line);
  766.  
  767.     sprintf (line+linelim, "%s", p->label);
  768.  
  769.     linelim += strlen (line+linelim);
  770.  
  771. }
  772.  
  773.  
  774.  
  775. printfile (fname) {
  776.  
  777.     FILE *f = fopen(fname, "w");
  778.  
  779.     char pline[1000];
  780.  
  781.     int plinelim;
  782.  
  783.     register row, col;
  784.  
  785.     register struct ent **p;
  786.  
  787.     if (f==0) {
  788.  
  789.     error ("Can't create %s", fname);
  790.  
  791.     return;
  792.  
  793.     }
  794.  
  795.     for (row=0;row<=maxrow; row++) {
  796.  
  797.     register c = 0;
  798.  
  799.     plinelim = 0;
  800.  
  801.     for (p = &tbl[row][col=0]; col<=maxcol; col++, p++) {
  802.  
  803.         if (*p) {
  804.  
  805.         char *s;
  806.  
  807.         while (plinelim<c) pline[plinelim++] = ' ';
  808.  
  809.         plinelim = c;
  810.  
  811.         if ((*p)->flags&is_valid) {
  812.  
  813.             sprintf (pline+plinelim,"%*.*f",fwidth[col],precision[col],
  814.  
  815.                 (*p)->v);
  816.  
  817.             plinelim += strlen (pline+plinelim);
  818.  
  819.         }
  820.  
  821.         if (s = (*p)->label) {
  822.  
  823.             register char *d;
  824.  
  825.             d = pline+((*p)->flags&is_leftflush
  826.  
  827.             ? c : c-strlen(s)+fwidth[col]);
  828.  
  829.             while (d>pline+plinelim) pline[plinelim++] = ' ';
  830.  
  831.             if (d<pline) d = pline;
  832.  
  833.             while (*s) *d++ = *s++;
  834.  
  835.             if (d-pline>plinelim) plinelim = d-pline;
  836.  
  837.         }
  838.  
  839.         }
  840.  
  841.         c += fwidth [col];
  842.  
  843.     }
  844.  
  845.     fprintf (f,"%.*s\n",plinelim,pline);
  846.  
  847.     }
  848.  
  849.     fclose (f);
  850.  
  851. }
  852.  
  853.  
  854.  
  855. tblprintfile (fname) {
  856.  
  857.     FILE *f = fopen(fname, "w");
  858.  
  859.     char pline[1000];
  860.  
  861.     int plinelim;
  862.  
  863.     register row, col;
  864.  
  865.     register struct ent **p;
  866.  
  867.     char coldelim = DEFCOLDELIM;
  868.  
  869.  
  870.  
  871.     if (f==0) {
  872.  
  873.     error ("Can't create %s", fname);
  874.  
  875.     return;
  876.  
  877.     }
  878.  
  879.     for (row=0;row<=maxrow; row++) {
  880.  
  881.     register c = 0;
  882.  
  883.     plinelim = 0;
  884.  
  885.     for (p = &tbl[row][col=0]; col<=maxcol; col++, p++) {
  886.  
  887.         if (*p) {
  888.  
  889.         char *s;
  890.  
  891.         if ((*p)->flags&is_valid) {
  892.  
  893.             fprintf (f,"%.*f",precision[col],
  894.  
  895.                 (*p)->v);
  896.  
  897.         }
  898.  
  899.         if (s = (*p)->label) {
  900.  
  901.                 fprintf (f,"%s",s);
  902.  
  903.         }
  904.  
  905.         }
  906.  
  907.         fprintf(f,"%c",coldelim);
  908.  
  909.     }
  910.  
  911.     fprintf (f,"\n",pline);
  912.  
  913.     }
  914.  
  915.     fclose (f);
  916.  
  917. }
  918.  
  919.  
  920.  
  921. struct enode *copye (e, Rdelta, Cdelta)
  922.  
  923. register struct enode *e; {
  924.  
  925.     register struct enode *ret;
  926.  
  927.     if (e==0) ret = 0;
  928.  
  929.     else {
  930.  
  931.     ret = (struct enode *) malloc (sizeof (struct enode));
  932.  
  933.     ret->op = e->op;
  934.  
  935.     switch (ret->op) {
  936.  
  937.     case 'v':
  938.  
  939.         ret->e.v = lookat (e->e.v->row+Rdelta, e->e.v->col+Cdelta);
  940.  
  941.         break;
  942.  
  943.     case 'k':
  944.  
  945.         ret->e.k = e->e.k;
  946.  
  947.         break;
  948.  
  949.     case 'f':
  950.  
  951.         ret->e.o.right = copye (e->e.o.right,0,0);
  952.  
  953.         ret->e.o.left = 0;
  954.  
  955.          break;
  956.  
  957.      case O_REDUCE('+'):
  958.  
  959.      case O_REDUCE('*'):
  960.  
  961.      case O_REDUCE('a'):
  962.  
  963.          ret->e.o.right = (struct enode *) lookat (
  964.  
  965.                    ((struct ent *)e->e.o.right)->row+Rdelta,
  966.  
  967.                    ((struct ent *)e->e.o.right)->col+Cdelta
  968.  
  969.             );
  970.  
  971.          ret->e.o.left = (struct enode *) lookat (
  972.  
  973.                    ((struct ent *)e->e.o.left)->row+Rdelta,
  974.  
  975.                    ((struct ent *)e->e.o.left)->col+Cdelta
  976.  
  977.             );
  978.  
  979.         break;
  980.  
  981.     default:
  982.  
  983.         ret->e.o.right = copye (e->e.o.right,Rdelta,Cdelta);
  984.  
  985.         ret->e.o.left = copye (e->e.o.left,Rdelta,Cdelta);
  986.  
  987.         break;
  988.  
  989.     }
  990.  
  991.     }
  992.  
  993.     return ret;
  994.  
  995. }
  996.  
  997.  
  998.  
  999. /*
  1000.  
  1001.  * sync_refs and sync_ref are used to remove references to
  1002.  
  1003.  * deleted struct ents.  Note that the deleted structure must still
  1004.  
  1005.  * be hanging around before the call, but not referenced by an entry
  1006.  
  1007.  * in tbl.  Thus the free_ent, fix_ent calls in sc.c
  1008.  
  1009.  */
  1010.  
  1011.  
  1012.  
  1013. sync_refs () {
  1014.  
  1015.     register i,j;
  1016.  
  1017.     register struct ent *p;
  1018.  
  1019.     for (i=0; i<=maxrow; i++)
  1020.  
  1021.     for (j=0; j<=maxcol; j++)
  1022.  
  1023.         if ((p=tbl[i][j]) && p->expr)
  1024.  
  1025.         sync_ref(p->expr);
  1026.  
  1027. }
  1028.  
  1029.  
  1030.  
  1031.  
  1032.  
  1033. sync_ref(e)
  1034.  
  1035. register struct enode *e;
  1036.  
  1037. {
  1038.  
  1039.     if (e==0)
  1040.  
  1041.     return;
  1042.  
  1043.     else {
  1044.  
  1045.     switch (e->op) {
  1046.  
  1047.     case 'v':
  1048.  
  1049.         e->e.v = lookat(e->e.v->row, e->e.v->col);
  1050.  
  1051.         break;
  1052.  
  1053.     case 'k':
  1054.  
  1055.         break;
  1056.  
  1057.      case O_REDUCE('+'):
  1058.  
  1059.      case O_REDUCE('*'):
  1060.  
  1061.      case O_REDUCE('a'):
  1062.  
  1063.          e->e.o.right = (struct enode *) lookat (
  1064.  
  1065.                    ((struct ent *)e->e.o.right)->row,
  1066.  
  1067.                    ((struct ent *)e->e.o.right)->col
  1068.  
  1069.             );
  1070.  
  1071.          e->e.o.left = (struct enode *) lookat (
  1072.  
  1073.                    ((struct ent *)e->e.o.left)->row,
  1074.  
  1075.                    ((struct ent *)e->e.o.left)->col
  1076.  
  1077.             );
  1078.  
  1079.         break;
  1080.  
  1081.     default:
  1082.  
  1083.         sync_ref(e->e.o.right);
  1084.  
  1085.         sync_ref(e->e.o.left);
  1086.  
  1087.         break;
  1088.  
  1089.     }
  1090.  
  1091.     }
  1092.  
  1093. }
  1094.  
  1095.  
  1096.  
  1097. hiderow(arg)
  1098.  
  1099. {
  1100.  
  1101.     register int r1;
  1102.  
  1103.     register int r2;
  1104.  
  1105.  
  1106.  
  1107.     r1 = currow;
  1108.  
  1109.     r2 = r1 + arg - 1;
  1110.  
  1111.     if (r1 < 0 || r1 > r2) {
  1112.  
  1113.     error("Invalid Range");
  1114.  
  1115.     return;
  1116.  
  1117.     }
  1118.  
  1119.     if (r2 > MAXROWS-2) {
  1120.  
  1121.     error("You can't hide the last row");
  1122.  
  1123.     return;
  1124.  
  1125.     }
  1126.  
  1127.     FullUpdate++;
  1128.  
  1129.     while (r1 <= r2)
  1130.  
  1131.     hidden_row[r1++] = 1;
  1132.  
  1133. }
  1134.  
  1135.  
  1136.  
  1137. hidecol(arg)
  1138.  
  1139. {
  1140.  
  1141.     register int c1;
  1142.  
  1143.     register int c2;
  1144.  
  1145.  
  1146.  
  1147.     c1 = curcol;
  1148.  
  1149.     c2 = c1 + arg - 1;
  1150.  
  1151.     if (c1 < 0 || c1 > c2) {
  1152.  
  1153.     error("Invalid Range");
  1154.  
  1155.     return;
  1156.  
  1157.     }
  1158.  
  1159.     if (c2 > MAXCOLS-2) {
  1160.  
  1161.     error("You can't hide the last col");
  1162.  
  1163.     return;
  1164.  
  1165.     }
  1166.  
  1167.     FullUpdate++;
  1168.  
  1169.     while (c1 <= c2)
  1170.  
  1171.     hidden_col[c1++] = 1;
  1172.  
  1173. }
  1174.  
  1175.  
  1176.  
  1177. showrow(r1, r2)
  1178.  
  1179. {
  1180.  
  1181.     if (r1 < 0 || r1 > r2) {
  1182.  
  1183.     error("Invalid Range");
  1184.  
  1185.     return;
  1186.  
  1187.     }
  1188.  
  1189.     if (r2 > MAXROWS-1) {
  1190.  
  1191.     r2 = MAXROWS-1;
  1192.  
  1193.     }
  1194.  
  1195.     FullUpdate++;
  1196.  
  1197.     while (r1 <= r2)
  1198.  
  1199.     hidden_row[r1++] = 0;
  1200.  
  1201. }
  1202.  
  1203.  
  1204.  
  1205. showcol(c1, c2)
  1206.  
  1207. {
  1208.  
  1209.     if (c1 < 0 || c1 > c2) {
  1210.  
  1211.     error("Invalid Range");
  1212.  
  1213.     return;
  1214.  
  1215.     }
  1216.  
  1217.     if (c2 > MAXCOLS-1) {
  1218.  
  1219.     c2 = MAXCOLS-1;
  1220.  
  1221.     }
  1222.  
  1223.     FullUpdate++;
  1224.  
  1225.     while (c1 <= c2)
  1226.  
  1227.     hidden_col[c1++] = 0;
  1228.  
  1229. }
  1230.  
  1231.